package br.mia.unifor.onaga.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

import br.mia.unifor.onaga.cloud.artifact.script.Scriptlet;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;

public class SSHClient {

	private static Logger logger = Logger.getLogger(SSHClient.class.getName());
	
	public static boolean exec(Scriptlet commands, String user, String host,
			String credential, Boolean password) {
		boolean retorno = true;
		for (String command : commands.getScripts()) {
			retorno &= exec(command, user, host, credential, password);
		}
		
		return retorno;
	}

	public static boolean exec(String command, String user, String host,
			String credential, Boolean password) {

		JSch jsch = new JSch();

		Session session = null;
		Channel channel = null;
		try {
			session = jsch.getSession(user, host, 22);

			// username and password will be given via UserInfo interface.
			UserInfo ui = new MyUserInfo(credential, password);
			session.setUserInfo(ui);

			if (ui.getPassphrase() != null) {
				jsch.addIdentity(ui.getPassphrase());
			}

			session.connect();

			channel = session.openChannel("exec");
			((ChannelExec) channel).setCommand(command);

			// X Forwarding
			// channel.setXForwarding(true);

			// channel.setInputStream(System.in);
			channel.setInputStream(null);

			// channel.setOutputStream(System.out);

			// FileOutputStream fos=new FileOutputStream("/tmp/stderr");
			// ((ChannelExec)channel).setErrStream(fos);
			((ChannelExec) channel).setErrStream(System.err);

			InputStream in = channel.getInputStream();

			channel.connect();

			byte[] tmp = new byte[1024];
			int j =0;
			while (j < 6) {
				++j;
				while (in.available() > 0) {
					int i = in.read(tmp, 0, 1024);
					if (i < 0)
						break;
					System.out.print(new String(tmp, 0, i));
				}
				if (channel.isClosed()) {
					System.out.println("exit-status: "
							+ channel.getExitStatus());
					break;
				}
				try {
					Thread.sleep(5000);
				} catch (Exception ee) {
				}
			}

		} catch (JSchException e) {
			logger.log(Level.SEVERE, "erro ao conectar ao servidor remoto", e);
		} catch (IOException e) {
			logger.log(Level.SEVERE, "erro ao conectar ao executar o comando",
					e);
		} finally {
			channel.disconnect();
			session.disconnect();
		}

		return true;
	}

	public static class MyUserInfo implements UserInfo {
		private final String credential;
		private final Boolean password;

		public MyUserInfo(String credential, Boolean password) {
			this.credential = credential;
			this.password = password;
		}

		public String getPassphrase() {
			if (password) {
				return null;
			} else {
				return credential;
			}
		}

		public String getPassword() {
			if (password) {
				return credential;
			} else {
				return null;
			}

		}

		public boolean promptPassphrase(String arg0) {
			return true;
		}

		public boolean promptPassword(String arg0) {
			return true;
		}

		public boolean promptYesNo(String arg0) {
			return true;
		}

		public void showMessage(String arg0) {
			logger.info(arg0);
		}

	}

	public static void main(String[] args) {
		SSHClient.exec("ls -lah", args[0], args[1], args[2], false);
	}
}
